﻿using System;
using System.Collections.Generic;

using ExtensibleEventViewer.Console.DomainModel;
using ExtensibleEventViewer.Console.EventArguments;
using ExtensibleEventViewer.Console.Properties;
using ExtensibleEventViewer.Core.Interfaces;
using ExtensibleEventViewer.Core.Primitives;


namespace ExtensibleEventViewer.Console.Forms
{
	/// <summary>
	/// Represents window where user can select 
	/// </summary>
	public partial class EventLogListWnd : FormBase
	{
		private readonly IEnumerable<string> _computerNameList;
		private readonly IEnumerable<IEventLogProvider> _providerList;
		private readonly List<TrackedEventLog> _trackedLogList;

		internal Action<IEnumerable<TrackedEventLog>> SaveMonitoredEventLogList;

		public EventLogListWnd()
			: base(Resources.EventLogListWindowTitle)
		{
			
		}

		/// <summary>
		/// Initializes form instance
		/// </summary>
		internal EventLogListWnd(
			IEnumerable<string> computerNameList, 
			IEnumerable<IEventLogProvider> providerList, 
			IEnumerable<TrackedEventLog> trackedLogList)
			: base(Resources.EventLogListWindowTitle)
		{
			InitializeComponent();

			_computerNameList = computerNameList;
			_providerList = providerList;
			_trackedLogList = FilterTrackedEventLogs(computerNameList, providerList, trackedLogList);

			eventLogList.EventLogTrackStatusChanged += EventLogTrackStatusChanged;

			Load += LoadData;
		}

		private void EventLogTrackStatusChanged(object sender, EventLogTrackStatusChangedEventArgs args)
		{
			if (_trackedLogList.Contains(args.EventLog))
			{
				if (!args.IsTracked)
				{
					_trackedLogList.Remove(args.EventLog);
				}
			}
			else if (args.IsTracked)
			{
				_trackedLogList.Add(args.EventLog);
			}
		}

		private void LoadData(object sender, EventArgs e)
		{
			computerListFilter.SelectedComputerChanged += ComputerNameChanged;
			eventLogProviderListFilter.SelectedProviderChanged += SelectedProviderChanged;

			ReloadEventRecordList(eventLogProviderListFilter.SelectedEventLogProvider, computerListFilter.SelectedComputerName);
		}


		private void Save(object sender, EventArgs e)
		{
			if (SaveMonitoredEventLogList != null)
			{
				SaveMonitoredEventLogList(_trackedLogList);
			}

			CloseWindow(sender, e);
		}

		private static List<TrackedEventLog> FilterTrackedEventLogs(
			IEnumerable<string> computerNameList,
			IEnumerable<IEventLogProvider> providerList,
			IEnumerable<TrackedEventLog> trackedLogList)
		{
			List<TrackedEventLog> result = new List<TrackedEventLog>();

			foreach (TrackedEventLog eventLog in trackedLogList)
			{
				foreach (string computerName in computerNameList)
				{
					if (string.Equals(computerName, eventLog.ComputerName, StringComparison.InvariantCultureIgnoreCase))
					{
						foreach (IEventLogProvider provider in providerList)
						{
							if (string.Equals(provider.ProviderID, eventLog.ProviderID))
							{
								result.Add(eventLog);
							}
						}
					}
				}
			}

			return result;
		}

		private void CloseWindow(object sender, EventArgs e)
		{
			Close();
		}

		protected override void OnClosing(System.ComponentModel.CancelEventArgs e)
		{
			AppSettings.Instance.ComputerList = new List<string>(computerListFilter.ComputerList).ToArray();

			base.OnClosing(e);
		}

		private void ComputerNameChanged(string computerName)
		{
			ReloadEventRecordList(eventLogProviderListFilter.SelectedEventLogProvider, computerListFilter.SelectedComputerName);
		}

		private void SelectedProviderChanged(object sender, SelectedProviderChangedEventArgs args)
		{
			ReloadEventRecordList(args.EventLogProvider, computerListFilter.SelectedComputerName);
		}

		private void ReloadEventRecordList(IEventLogProvider provider, string computerName)
		{
			eventLogList.ClearList();

			if (provider == null || string.IsNullOrEmpty(computerName))
			{
				return;
			}

			EventLogConnector connector = new EventLogConnector(computerName, provider);

			eventLogList.LoadData(connector, _trackedLogList);
		}
	}
}